#pragma once
#include <set>
#include "Common.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"

using namespace LogModule;

class Command
{
public:
    Command()
    {
        // 严格匹配
        _WhiteListCommands.insert("ls");
        _WhiteListCommands.insert("pwd");
        _WhiteListCommands.insert("ls -l");
        _WhiteListCommands.insert("touch hello.txt");
        _WhiteListCommands.insert("who");
        _WhiteListCommands.insert("whoami");
    }

    // 判断命令是否合法
    bool IsSafeCommand(const std::string &cmd)
    {
        auto it = _WhiteListCommands.find(cmd);
        if (it == _WhiteListCommands.end())
        {
            return false;
        }
        return true;
    }

    // 是addr用户输入的cmd命令
    std::string Exeute(const std::string &cmd, InetAddr &addr)
    {
        // 1. 不属于白名单的命令
        if (!IsSafeCommand(cmd))
        {
            return std::string("该命令是禁止的");
        }

        std::string who = addr.StringAddr();

        // 2.执行命令
        // popen这个函数就是创建子进程把我们传入的命令执行完
        // 然后把结果返回到父进程的读端，通过文件形式返回读取结果
        FILE *fp = popen(cmd.c_str(), "r");
        if (fp == nullptr)
        {
            return std::string("你要执行的命令不存在：") + cmd;
        }

        std::string res;
        char line[1024];
        while (fgets(line, sizeof(line), fp))
        {
            res += line;
        }
        pclose(fp);
        std::string result = who + "execute done,result is: \n" + res;
        LOG(LogLevel::DEBUG) << result;
        return result;
    }

    ~Command()
    {
    }

private:
    // 受限制的远程执行
    std::set<std::string> _WhiteListCommands; // 白名单的命令集合
};